﻿using Database.ERPNext;
using Main.Configs;
using Main.Controls;
using Main.Tools;
using Main.ViewModels;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Main.Models
{
    public class VoucherToPrint
    {
        public string? currency { get; set; }
        public DateOnly? posting_date { get; set; }
        public string? company { get; set; }
        public string? voucher_no { get; set; }  
        public string? finance_manager { get; set; }
        public string? accounting_clerk { get; set; }
        public string? reviewer { get; set; }
        public string? voucher_maker { get; set; }

        public decimal sum { 
            get {                
                return details.Select(x=>x.debit).Sum();
            } 
        }

        public decimal debit_sum
        {
            get
            {
                return details.Select(x => x.debit).Sum();
            }
        }

        public decimal credit_sum
        {
            get
            {
                return details.Select(x => x.credit).Sum();
            }
        }

        public List<VoucherDetailToPrint> details { get; set; } = new List<VoucherDetailToPrint>();

        public List<VoucherPrintPaperViewModel> GetVoucherPrintPaperViewModels()
        {
            List<VoucherPrintPaperViewModel> result= new List<VoucherPrintPaperViewModel>();

            int count=this.details.Count/VoucherPrintConfig.Current.VoucherMaxRowCount + (this.details.Count%VoucherPrintConfig.Current.VoucherMaxRowCount==0 ? 0 : 1);

            decimal debit_sum = 0;
            decimal credit_sum = 0;
            for (int page=0; page<count;page++)
            {
                VoucherPrintPaperViewModel vm=new VoucherPrintPaperViewModel();
                vm.Currency = $"本币：{this.currency}  单位：元";
                vm.PostingDate = this.posting_date ?.ToString("yyyy年MM月dd日");
                vm.Company = $"编制单位：{this.company}";   
                vm.VoucherNo = $"{this.voucher_no}";
                vm.VoucherNoDetail = $"第{this.voucher_no}号 - {page + 1:0000}/{count:0000}";
                vm.FinanceManager = $"财务主管：{this.finance_manager}";
                vm.AccountingClerk = $"记账：{this.accounting_clerk}";
                vm.Reviewer = $"复核：{this.reviewer}";
                vm.VoucherMaker = $"制单：{this.voucher_maker}";
                
                
                for(int row = 0; row < VoucherPrintConfig.Current.VoucherMaxRowCount; row++)
                {
                    int index=page*VoucherPrintConfig.Current.VoucherMaxRowCount+row;
                    if (index >= this.details.Count)
                    {
                        break;
                    }

                    var detail= this.details[index];
                    //
                    vm.Remarks[row] = detail.remarks;

                    //
                    StringBuilder sb= new StringBuilder();
                    sb.Append($"{detail.account_no}/{detail.account_name}");
                    if (string.IsNullOrWhiteSpace(detail.cash_flow_dest))
                    {
                        sb.Append($" {detail.cash_flow_dest}");
                    }
                    if (string.IsNullOrWhiteSpace(detail.department))
                    {
                        sb.Append($" {detail.department}");
                    }
                    if (string.IsNullOrWhiteSpace(detail.party))
                    {
                        sb.Append($" {detail.party}");
                    }
                    vm.Accounts[row] = sb.ToString();

                    //
                    vm.Debits[row] = $"{detail.debit:0.00}";

                    //
                    vm.Credits[row] = $"{detail.credit:0.00}";

                    //
                    debit_sum += detail.debit;
                    credit_sum += detail.credit;
                }

                vm.DebitSum = $"{debit_sum:0.00}";
                vm.CreditSum = $"{credit_sum:0.00}";

                if (page >= count - 1)
                {
                    if (debit_sum != credit_sum)
                    {
                        Serilog.Log.Error($"【凭证打印】借贷不相等：借{vm.DebitSum}<>贷{vm.CreditSum}");
                    }

                    vm.Sum=$"合计 {RMBCapitalization.RMBAmount(debit_sum)}";
                }
                else
                {
                    vm.Sum = "合计";
                }
                
                result.Add( vm );
                
            }

            return result;
        }


        //public List<Bitmap> MakeBitmap()
        //{
        //    string path=Path.Combine(Directory.GetCurrentDirectory(), $"Templates/{VoucherPrintConfig.Current.TemplatePhoto}");
        //    Image bmp = Bitmap.FromFile(path);

        //    //凭证总页数
        //    int total_page_count = (this.details.Count / VoucherPrintConfig.Current.VoucherMaxRowCount) + ((this.details.Count % VoucherPrintConfig.Current.VoucherMaxRowCount > 0)? 1 : 0);

        //    List<Bitmap> result = new List<Bitmap>();

        //    for(int page = 0;page< total_page_count; page++)
        //    {
        //        using (Graphics g = Graphics.FromImage(bmp))
        //        {

        //            //币别
        //            _DrawStringAutoSize(g, this.currency, VoucherPrintConfig.Current.Rect_Currency);

        //            //日期
        //            _DrawStringAutoSize(g, this.posting_date.Value.ToString("yyyy年MM月dd日"), VoucherPrintConfig.Current.Rect_PostingDate);

        //            //公司
        //            _DrawStringAutoSize(g, this.company, VoucherPrintConfig.Current.Rect_Company);

        //            //凭证号等
        //            _DrawStringAutoSize(g, $"第{this.voucher_no}号 - {page+1:0000}/{total_page_count:0000} ", VoucherPrintConfig.Current.Rect_VocherNoMix);

        //            //合计
        //            _DrawStringAutoSize(g, RMBCapitalization.RMBAmount(this.sum), VoucherPrintConfig.Current.Rect_Sum);

        //            //借方合计
        //            _DrawStringAutoSize(g,$"{this.debit_sum:0.00}", VoucherPrintConfig.Current.Rect_SumDebit);

        //            //贷方合计
        //            _DrawStringAutoSize(g, $"{this.credit_sum:0.00}", VoucherPrintConfig.Current.Rect_SumCredit);

        //            //财务主管
        //            _DrawStringAutoSize(g, this.finance_manager, VoucherPrintConfig.Current.Rect_FinanceManager);

        //            //记账
        //            _DrawStringAutoSize(g, this.accounting_clerk, VoucherPrintConfig.Current.Rect_AccountingClerk);

        //            //复核
        //            _DrawStringAutoSize(g, this.reviewer, VoucherPrintConfig.Current.Rect_Reviewer);

        //            //制单
        //            _DrawStringAutoSize(g, this.voucher_maker, VoucherPrintConfig.Current.Rect_VoucherMaker);

        //            for(int row=0;row< VoucherPrintConfig.Current.VoucherMaxRowCount; row++)
        //            {
        //                int index=page* VoucherPrintConfig.Current.VoucherMaxRowCount+row;
        //                if (row >= this.details.Count)
        //                {
        //                    break;
        //                }

        //                var detail = this.details[index];

        //                //摘要
        //                _DrawStringAutoSize(g, detail.remarks, VoucherPrintConfig.Current.Rect_Remarks,row);

        //                //科目
        //                StringBuilder builder = new StringBuilder();
        //                builder.Append($"{detail.account_no}/{detail.account_name}");
        //                if (!string.IsNullOrEmpty(detail.cash_flow_dest))
        //                {
        //                    builder.Append($" {detail.cash_flow_dest}");
        //                }
        //                if (!string.IsNullOrEmpty(detail.department))
        //                {
        //                    builder.Append($" {detail.department}");
        //                }
        //                if (!string.IsNullOrEmpty(detail.party))
        //                {
        //                    builder.Append($" {detail.party}");
        //                }
        //                _DrawStringAutoSize(g, builder.ToString(), VoucherPrintConfig.Current.Rect_AccountMix, row);

        //                //借方金额
        //                _DrawStringAutoSize(g, $"{detail.debit:0.00}", VoucherPrintConfig.Current.Rect_Debit, row);

        //                //贷方金额
        //                _DrawStringAutoSize(g, $"{detail.credit:0.00}", VoucherPrintConfig.Current.Rect_Credit, row);
        //            }
        //        }

        //        bmp.Save("d:\\test.png", ImageFormat.Png);

        //        result.Add(bmp as Bitmap);
        //    }



        //    return result;
            
        //}

        //void _DrawStringAutoSize(Graphics g, string? text, RectAndAlignment rect, int row=0)
        //{
            
        //    g.PageUnit = GraphicsUnit.Pixel;
        //    if(string.IsNullOrWhiteSpace(text))
        //    {
        //        return;
        //    }

        //    float font_size = VoucherPrintConfig.Current.BaseFontSize;

        //    float rect_width = rect.xBottomRight - rect.xTopLeft;
        //    float rect_height=rect.yBottomRight - rect.yTopLeft;

        //    StringFormat format = new StringFormat();
        //    format.FormatFlags = StringFormatFlags.LineLimit; // 设置自动换行
        //    format.Alignment = rect.horizontal_alignment;
        //    format.LineAlignment = rect.vertical_alignment;


        //    rect_height += VoucherPrintConfig.Current.FontHeightCompensation;//补偿字体头部和尾部空间
        //    rect_width += VoucherPrintConfig.Current.FontWidthCompensation;//补偿字体左右空间

        //    Font tempFont = new Font(VoucherPrintConfig.Current.FontFamily, font_size); // 默认字体
        //    while (true)
        //    {
        //        if(font_size<= VoucherPrintConfig.Current.MinFontSize)
        //        {
        //            break;
        //        }

        //        //SizeF textSize = g.MeasureString(text, tempFont,new SizeF(rect_width,rect_height),format,out int charFitted, out int linesFilled);

        //        //if(textSize.Width < rect_width && textSize.Height < rect_height)
        //        //{
        //        //    break;
        //        //}

        //        SizeF textSize = g.MeasureString(text, tempFont, new SizeF(rect_width, rect_height), format, out int charFitted, out int linesFilled);

        //        if (charFitted==text.Length)
        //        {
        //            break;
        //        }


        //        font_size -= 1;
        //        tempFont = new Font(VoucherPrintConfig.Current.FontFamily, font_size); // 默认字体
        //    }

        //    RectangleF rect_layout = new RectangleF(rect.xTopLeft, rect.yTopLeft+VoucherPrintConfig.Current.VoucherMinRowStep*row, rect_width, rect_height);
            
        //    g.DrawString(text, tempFont, Brushes.Black, rect_layout, format);
        //}


        public static VoucherToPrint? GetVoucherToPrint(string voucher_no)
        {
            try
            {
                var gl_entries = Database.ERPNext.ERPNextDbContext.Current.tabGL_Entries.Where(x => x.voucher_no == voucher_no).OrderBy(x=>x.creation).ToArray();
                if (gl_entries.Length > 0)
                {
                    VoucherToPrint voucherToPrint = new VoucherToPrint();

                    //【币别】
                    var currency= gl_entries[0].account_currency;
                    voucherToPrint.currency = Database.ERPNext.ERPNextDbContext.Current.tabCurrencies.Where(x=>x.name == currency).Select(x=>x.currency_name).FirstOrDefault();

                    //【记账日期】
                    voucherToPrint.posting_date = gl_entries[0].posting_date;

                    //【公司】
                    voucherToPrint.company= gl_entries[0].company;

                    //【凭证编号】
                    voucherToPrint.voucher_no = gl_entries[0].voucher_no;

                    //【财务主管】
                    voucherToPrint.finance_manager = string.IsNullOrWhiteSpace(gl_entries[0].custom_财务主管)?VoucherPrintConfig.Current.DefaultFinanceManager: gl_entries[0].custom_财务主管;

                    //【记账人】
                    voucherToPrint.accounting_clerk = string.IsNullOrWhiteSpace(gl_entries[0].custom_记账人) ? VoucherPrintConfig.Current.DefaultAccountingClerk : gl_entries[0].custom_记账人;

                    //【复核人】
                    voucherToPrint.reviewer = string.IsNullOrWhiteSpace(gl_entries[0].custom_复核人) ? VoucherPrintConfig.Current.DefaultReviewer : gl_entries[0].custom_复核人;

                    //【制单人】
                    voucherToPrint.voucher_maker = string.IsNullOrWhiteSpace(gl_entries[0].custom_制单人) ? VoucherPrintConfig.Current.DefaultVoucherMaker : gl_entries[0].custom_制单人;

                    //详细条目
                    foreach(var gl in gl_entries)
                    {
                        VoucherDetailToPrint detailToPrint = new VoucherDetailToPrint();
                        //【备注】
                        detailToPrint.remarks = gl.remarks;

                        //【科目代码】
                        var account= gl.account;                        
                        detailToPrint.account_no = account!.Substring(0,account.IndexOf(" - "));

                        //【科目名称】
                        detailToPrint.account_name=Database.ERPNext.ERPNextDbContext.Current.tabAccounts.Where(x=>x.name==account).Select(x=>x.account_name).FirstOrDefault();

                        //【现金流量项目】
                        detailToPrint.cash_flow_dest = gl.custom_现金流量项目;

                        //【部门】
                        detailToPrint.department = gl.custom_部门;

                        //【往来单位】
                        detailToPrint.party = gl.party;

                        //【借方金额】
                        detailToPrint.debit = gl.debit;

                        //【贷方金额】
                        detailToPrint.credit = gl.credit;

                        voucherToPrint.details.Add(detailToPrint);

                    }

                    //
                    return voucherToPrint;

                }
                return null;
            }
            catch(Exception ex) {
                Serilog.Log.Error($"【数据】凭证获取打印数据时出错：【错误】= {ex.Message}");
                return null;
            }           
            
        }


        /// <summary>
        /// 获取某月的计提折旧凭证
        /// </summary>
        /// <param name="date">月份</param>
        /// <param name="depreciationDetailToPrints">生成的折旧明细表</param>
        /// <returns>用于打印的凭证</returns>
        public static VoucherToPrint? GetDepreciationVoucherToPrint(DateOnly date, out List<DepreciationDetailToPrint> depreciationDetailToPrints)
        {
            depreciationDetailToPrints=new List<DepreciationDetailToPrint> ();
            return null;
        }


        public static List<VoucherToPrint> MakeVochersToPrint(IEnumerable<tabGL_Entry> gL_Entries,CancellationToken token,bool onlyNotYetPrinted)
        {
            List<VoucherToPrint> re=new List<VoucherToPrint> ();
            var voucher_numbers=gL_Entries.Select(x => x.voucher_no).Distinct().OrderBy(x=>x).ToList();
            if(onlyNotYetPrinted)
            {
                //去除已经打印的
                int count=voucher_numbers.Count();
                for(int i = count - 1; i >= 0; i--)
                {
                    var found=Database.ERPNext.ERPNextDbContext.Current.TabVoucherPrintHistories.Where(x => x.voucher_no == voucher_numbers[i]).FirstOrDefault();//注意不能用First()，空集合会引发异常
                    if (found != null)
                    {
                        voucher_numbers.RemoveAt(i);
                    }
                }

            }

            if (voucher_numbers.Count <= 0)
            {
                Serilog.Log.Information($"【凭证打印】无可打印条目");
            }

            foreach(var voucher_no in voucher_numbers)
            {
                var gls = Database.ERPNext.ERPNextDbContext.Current.tabGL_Entries.Where(x => x.voucher_no == voucher_no).ToList();

                if(token.IsCancellationRequested)
                {                    
                    return new List<VoucherToPrint> ();
                }

                if (gls.Count>0)
                {
                    VoucherToPrint voucher = new VoucherToPrint();
                    voucher.currency = Database.ERPNext.ERPNextDbContext.Current.tabCurrencies.Where(x=>x.name== gls[0].account_currency).Select(x=>x.currency_name).FirstOrDefault();
                    voucher.posting_date = gls[0].posting_date;
                    voucher.company = gls[0].company;
                    voucher.voucher_no = gls[0].voucher_no;
                    voucher.finance_manager = VoucherPrintConfig.Current.DefaultFinanceManager;
                    voucher.accounting_clerk=VoucherPrintConfig.Current.DefaultAccountingClerk;
                    voucher.reviewer = VoucherPrintConfig.Current.DefaultReviewer;
                    voucher.voucher_maker = VoucherPrintConfig.Current.DefaultVoucherMaker;

                    foreach (var gl in gls)
                    {
                        var detail=new VoucherDetailToPrint();
                        detail.remarks=gl.remarks;
                        detail.account_no = Database.ERPNext.ERPNextDbContext.Current.tabAccounts.Where(x=>x.name==gl.account).Select(x=>x.account_number).FirstOrDefault();
                        detail.account_name= Database.ERPNext.ERPNextDbContext.Current.tabAccounts.Where(x => x.name == gl.account).Select(x => x.account_name).FirstOrDefault();
                        detail.cash_flow_dest = gl.custom_现金流量项目;
                        detail.department = gl.custom_部门;
                        if (gl.party!=null && gl.party.StartsWith("HR-EMP"))//是员工，则转换为姓名
                        {
                            detail.party=Database.ERPNext.ERPNextDbContext.Current.tabEmployees.Where(x=>x.employee==gl.party).Select(x=>x.employee_name).FirstOrDefault();
                        }
                        else
                        {
                            detail.party = gl.party;
                        }
                        detail.debit = gl.debit;
                        detail.credit = gl.credit;
                        
                        //
                        voucher.details.Add(detail);
                    }

                    re.Add(voucher);
                    Serilog.Log.Information($"【凭证打印】生成打印数据：{voucher.voucher_no}");
                }

                
            }
            return re;
        }

        
    }
}
